﻿//using System;
//using System.Collections.Generic;
//using System.Text;
//using ZhCun.Framework.Common.Models.TableModel;
//using ZhCun.Framework.DataAccess.DbHelper;
//using ZhCun.Framework.DataAccess.BuildSQLText;
//using System.Data.Common;
//using ZhCun.Framework.Common.Models;
//using ZhCun.Framework.Common.Exceptions;
//using ZhCun.Framework.Common.Models.ProcedureModel;
//using System.Data;

//namespace ZhCun.Framework.DataAccess.DAL
//{
//    public abstract class DalBase<TModel> where TModel : ModelBase, new()
//    {
//        #region 抽象方法,由具体数据类实现

//        /// <summary>
//        /// 访问数据的DBHelper对象
//        /// </summary>
//        protected internal abstract IDbHelper DBHelper { get; } //子类实现
//        /// <summary>
//        /// 获得生成sql文本的对象
//        /// </summary>
//        protected internal abstract BuildSQL BuildSQLTextObj { get; }
//        /// <summary>
//        /// 获得数据参数对象
//        /// </summary>
//        protected internal abstract DbParameter GetDbParam(string paramName, object paramValue);
//        /// <summary>
//        /// 将whereModel转换成dal所需的参数类型的对象,
//        /// </summary>
//        protected internal abstract WhereParamBase WhereParamHelper { get; } //2013.3.26 因考虑所有sql语句的生成都应由dal实现

//        #endregion

//        #region where条件对象化查询

//        /// <summary>
//        /// 将一个list实体参数对象,转换成参数对象,加上括号
//        /// </summary>
//        protected internal void GetSqlWhereParam(ref StringBuilder sqlWhere, ref Dictionary<string, object> paramDict, params DbWhereModel[] whereModel)
//        {
//            WhereParamHelper.GetSqlWhereParam(ref sqlWhere, ref paramDict, whereModel);
//        }
//        /// <summary>
//        /// 将一个或多个list实体参数对象,转换成参数对象,加上括号(每个list会加上括号)
//        /// </summary>
//        protected internal void GetSqlWhereParam(ref StringBuilder sqlWhere, ref Dictionary<string, object> paramDict, params DbWhereModel[][] sqlWhereGroup)
//        {
//            WhereParamHelper.GetSqlWhereParam(ref sqlWhere, ref paramDict, sqlWhereGroup);
//        }

//        #endregion

//        #region 生成sql语句的方法

//        /// <summary>
//        /// 生成Insert SQL语句
//        /// </summary>
//        protected internal virtual void GenerateInsertSQLTextAndParam(out string sqlText, out Dictionary<string, object> dbParams, params TModel[] models)
//        {
//            BuildSQLTextObj.GenerateInsertSQLTextAndParam(out sqlText, out dbParams, models);
//        }
//        /// <summary>
//        /// 生成Update SQL语句
//        /// </summary>
//        protected internal virtual void GenerateUpdateSQLTextAndParam(out string sqlText, ref Dictionary<string, object> dbParams, string sqlWhere, string[] updateFields, params TModel[] models)
//        {
//            BuildSQLTextObj.GenerateUpdateSQLTextAndParam(out sqlText, ref dbParams, sqlWhere, updateFields, models);
//        }
//        /// <summary>
//        /// 生成Delete SQL语句
//        /// </summary>
//        protected internal virtual void GenerateDeleteSQLTextAndParam(out string sqlText, out Dictionary<string, object> dbParams, params object[] pkValues)
//        {
//            BuildSQLTextObj.GenerateDeleteSQLTextAndParam<TModel>(out sqlText, out dbParams, pkValues);
//        }
//        /// <summary>
//        /// 生成判断存在的 SQL语句
//        /// </summary>
//        protected internal virtual void GenerateIsExistSQLText(object pkeyValue, string fieldName, object fieldValue, string sqlWhere, ref Dictionary<string, object> dbParams, out string sqlText)
//        {
//            BuildSQLTextObj.GenerateIsExistSQLText<TModel>(pkeyValue, fieldName, fieldValue, sqlWhere, ref dbParams, out sqlText);
//        }
//        /// <summary>
//        /// 生成统计数量的 SQL语句
//        /// </summary>
//        protected internal virtual void GenerateCountSQLTextAndParam(string sqlWhere, Dictionary<string, object> dbParams, out string sqlText)
//        {
//            BuildSQLTextObj.GenerateCountSQLTextAndParam<TModel>(sqlWhere, dbParams, out sqlText);
//        }
//        /// <summary>
//        /// 生成普通查询的SQL语句
//        /// </summary>
//        protected internal virtual void GenerateSearchSQLTextAndParam(string sqlWhere, Dictionary<string, object> dbParams, string[] orderFields, bool isDesc, out string sqlText, params string[] selectFields)
//        {
//            BuildSQLTextObj.GenerateSearchSQLTextAndParam<TModel>(sqlWhere, dbParams, orderFields, isDesc, out sqlText, selectFields);
//        }
//        /// <summary>
//        /// 生成前几行数据的SQL语句
//        /// </summary>
//        protected internal virtual void GenerateTopCountSQLText(int topCount, string sqlWhere, Dictionary<string, object> dbParams, string[] orderFields, bool isDesc, out string sqlText, params string[] selectFields)
//        {
//            BuildSQLTextObj.GenerateTopCountSQLText<TModel>(topCount, sqlWhere, dbParams, orderFields, isDesc, out sqlText, selectFields);
//        }
//        /// <summary>
//        /// 生成分页的sql语句SQL语句
//        /// </summary>
//        protected internal virtual void GeneratePageSQLTextAndParam(int onePageCount, int pageNo, bool isDesc, string[] orderFields, int recordCount, string sqlWhere, Dictionary<string, object> dbParams, out string sqlText, params string[] selectFields)
//        {
//            BuildSQLTextObj.GeneratePageSQLTextAndParam<TModel>(onePageCount, pageNo, isDesc, orderFields, recordCount, sqlWhere, dbParams, out sqlText, selectFields);
//        }

//        #endregion

//        #region 生成数据库参数对象

//        /// <summary>
//        /// 返回SQL参数查询.
//        /// Key如果不包含参数的@符号,则加上
//        /// </summary>
//        protected virtual DbParameter[] GetDbParam(Dictionary<string, object> dbParamsDict)
//        {
//            if (dbParamsDict == null || dbParamsDict.Keys.Count == 0) return null;
//            List<DbParameter> paramList = new List<DbParameter>();
//            foreach (var item in dbParamsDict.Keys)
//            {
//                string pName = item;
//                if (item.Trim().Substring(0, 1) != "@")
//                {
//                    pName = "@" + pName;
//                }
//                paramList.Add(GetDbParam(item, dbParamsDict[item]));
//            }
//            return paramList.ToArray();
//        }

//        #endregion

//        #region 执行的sql语句,增删改

//        protected void ThrowModelIsNullException(params TModel[] models)
//        {
//            if (models == null || models.Length == 0)
//            {
//                string errMsg = string.Format("在 {0} 对象中执行增加时失败,实体model为空!", BuildSQLTextObj.GetTableName<TModel>());
//                throw new FrameworkException(errMsg);
//            }
//        }
//        public int Add(params TModel[] models)
//        {
//            ThrowModelIsNullException(models);
//            string sqlText;
//            Dictionary<string, object> dbParams;
//            GenerateInsertSQLTextAndParam(out sqlText, out dbParams, models);
//            int rows = ExecuteBySQL(sqlText, dbParams);
//            return rows;
//        }

//        public int Update(string[] fields, string sqlWhere, Dictionary<string, object> dbParams, params TModel[] models)
//        {
//            ThrowModelIsNullException(models);
//            string sqlText;
//            GenerateUpdateSQLTextAndParam(out sqlText, ref dbParams, sqlWhere, fields, models);
//            int rows = ExecuteBySQL(sqlText, dbParams);
//            return rows;
//        }

//        public int UpdateByIgnoreField(string[] ignoreFields, string sqlWhere, Dictionary<string, object> dbParams, params TModel[] models)
//        {
//            string[] allFields = BuildSQLTextObj.GetAllFields<TModel>();
//            string[] updateFields = BuildSQLTextObj.RemoveFields(allFields, ignoreFields);
//            return Update(updateFields, sqlWhere, dbParams, models);
//        }

//        public int Delete(params object[] pkValues)
//        {
//            string sqlText;
//            Dictionary<string, object> dbParams;
//            GenerateDeleteSQLTextAndParam(out sqlText, out dbParams, pkValues);
//            int rows = ExecuteBySQL(sqlText, dbParams);
//            return rows;
//        }

//        public int ExecuteBySQL(string sqlText, Dictionary<string, object> dbParams)
//        {

//            //执行sql语句的操作都由此方法实现
//            DbParameter[] parameters = GetDbParam(dbParams);
//            int rows = DBHelper.ExecNonQuery(sqlText, parameters);
//            return rows;
//        }

//        #region 执行事务

//        //事务的缓存,列表,静态是为了让多个事务在一个对象里,多个dal访问的是一个事务缓存
//        static Dictionary<Guid, Dictionary<string, Dictionary<string, object>>> _TransCacheDict;

//        void AddTran(Guid tranId, string sqlText, Dictionary<string, object> dbParam)
//        {
//            if (tranId == Guid.Empty) return;

//            if (_TransCacheDict == null)
//            {
//                _TransCacheDict = new Dictionary<Guid, Dictionary<string, Dictionary<string, object>>>();
//                var transIdDict = new Dictionary<string, Dictionary<string, object>>();
//                transIdDict.Add(sqlText, dbParam);
//                _TransCacheDict.Add(tranId, transIdDict);
//            }
//            else
//            {
//                if (_TransCacheDict.ContainsKey(tranId))
//                {
//                    while (_TransCacheDict[tranId].ContainsKey(sqlText))
//                    {
//                        //如果字典Key中包含sqlText,则一直循环加入空格
//                        sqlText = sqlText + " ";
//                    }
//                    _TransCacheDict[tranId].Add(sqlText, dbParam);
//                }
//                else
//                {
//                    var transIdDict = new Dictionary<string, Dictionary<string, object>>();
//                    transIdDict.Add(sqlText, dbParam);
//                    _TransCacheDict.Add(tranId, transIdDict);
//                }
//            }
//        }
                
//        #endregion

//        #endregion

//        #region 判断数据值是否存在

//        public virtual bool IsExist(object pkeyValue, string fieldName, object fieldValue, string sqlWhere, Dictionary<string, object> dbParams)
//        {
//            string sqlText;
//            GenerateIsExistSQLText(pkeyValue, fieldName, fieldValue, sqlWhere, ref dbParams, out sqlText);
//            DbParameter[] param = GetDbParam(dbParams);
//            object obj = DBHelper.GetScalar(sqlText, param);
//            int r = Convert.ToInt32(obj);
//            return r > 0 ? true : false;
//        }

//        #endregion

//        #region 根据主键获得首行首列

//        /// <summary>
//        /// 根据主键获得一个指定字段的值
//        /// </summary>
//        public virtual object GetObjectByField(string fieldName, object pkValue)
//        {
//            StringBuilder strSql = new StringBuilder();
//            string tableName = BuildSQLTextObj.GetTableName<TModel>();
//            string pkName = BuildSQLTextObj.GetPrimaryKeyName<TModel>();
//            strSql.AppendFormat("Select {0} From {1}", fieldName, tableName);
//            strSql.AppendFormat(" Where {0}=@{0} ", pkName);
//            Dictionary<string, object> dbParams = new Dictionary<string, object>();
//            dbParams.Add(pkName, pkValue);
//            DbParameter[] param = GetDbParam(dbParams);
//            object obj = DBHelper.GetScalar(strSql.ToString(), param);
//            return obj;
//        }

//        #endregion

//        #region 根据主键获得一个实体对象

//        public virtual TModel GetModel(object id)
//        {
//            StringBuilder sp = new StringBuilder();
//            string pkName = BuildSQLTextObj.GetPrimaryKeyName<TModel>();
//            sp.AppendFormat("where {0}=@{0}", pkName);
//            Dictionary<string, object> dbParams = new Dictionary<string, object>();
//            dbParams.Add("@" + pkName, id);
//            List<TModel> list = GetList(sp.ToString(), dbParams, null, false, null);
//            if (list != null && list.Count > 0)
//            {
//                return list[0];
//            }
//            return null;
//        }

//        #endregion

//        #region 获得记录数

//        //获得记录数,如果返回非数字后
//        public virtual int GetRecordCount(string sqlWhere, Dictionary<string, object> dbParams)
//        {
//            string sqlText;
//            GenerateCountSQLTextAndParam(sqlWhere, dbParams, out sqlText);
//            DbParameter[] param = GetDbParam(dbParams);
//            object obj = DBHelper.GetScalar(sqlText, param);
//            if (obj == null) return 0;
//            int recCount = Convert.ToInt32(obj);
//            return recCount;
//        }

//        #endregion

//        #region 获得DataTable的几个方法

//        public virtual DataTable GetDataTableBySQL(string sqlText, Dictionary<string, object> dbParams)
//        {
//            DbParameter[] param = GetDbParam(dbParams);
//            DataTable dt = DBHelper.GetDataTable(sqlText, param);
//            return dt;
//        }
//        public virtual DataTable GetDataTable(string sqlWhere, Dictionary<string, object> dbParams, string[] orderFields, bool isDesc, params string[] selectFields)
//        {
//            string sqlText;
//            GenerateSearchSQLTextAndParam(sqlWhere, dbParams, orderFields, isDesc, out sqlText, selectFields);
//            return GetDataTableBySQL(sqlText, dbParams);
//        }
//        public virtual DataTable GetDataTableByPage(int onePageCount, int pageNo, bool isDesc, string[] orderField, out int pageCount, out int recordCount, string sqlWhere, Dictionary<string, object> dbParams, params string[] selectFields)
//        {
//            string sqlText;
//            recordCount = GetRecordCount(sqlWhere, dbParams);
//            pageCount = (int)(Math.Ceiling(recordCount * 1.0 / onePageCount));
//            GeneratePageSQLTextAndParam(onePageCount, pageNo, isDesc, orderField, recordCount, sqlWhere, dbParams, out sqlText, selectFields);
//            return GetDataTableBySQL(sqlText, dbParams);
//        }
//        public virtual DataTable GetDataTableTopCount(int topCount, string sqlWhere, Dictionary<string, object> dbParams, string[] orderFields, bool isDesc, params string[] selectFields)
//        {
//            string sqlText;
//            GenerateTopCountSQLText(topCount, sqlWhere, dbParams, orderFields, isDesc, out sqlText, selectFields);
//            return GetDataTableBySQL(sqlText, dbParams);
//        }

//        #endregion

//        #region 获得DataReader的几个方法

//        public virtual DbDataReader GetDataReaderBySQL(string sqlText, Dictionary<string, object> dbParams)
//        {
//            DbParameter[] param = GetDbParam(dbParams);
//            DbDataReader reader = DBHelper.GetDataReader(sqlText, param);
//            return reader;
//        }
//        public virtual DbDataReader GetDataReader(string sqlWhere, Dictionary<string, object> dbParams, string[] orderFields, bool isDesc, params string[] selectFields)
//        {
//            string sqlText;
//            GenerateSearchSQLTextAndParam(sqlWhere, dbParams, orderFields, isDesc, out sqlText, selectFields);
//            return GetDataReaderBySQL(sqlText, dbParams);
//        }
//        public virtual DbDataReader GetDataReaderByPage(int onePageCount, int pageNo, bool isDesc, string[] orderFields, out int pageCount, out int recordCount, string sqlWhere, Dictionary<string, object> dbParams, params string[] selectFields)
//        {
//            string sqlText;
//            recordCount = GetRecordCount(sqlWhere, dbParams);
//            pageCount = (int)(Math.Ceiling(recordCount * 1.0 / onePageCount));
//            GeneratePageSQLTextAndParam(onePageCount, pageNo, isDesc, orderFields, recordCount, sqlWhere, dbParams, out sqlText, selectFields);
//            return GetDataReaderBySQL(sqlText, dbParams);
//        }
//        public virtual DbDataReader GetDataReaderTopCount(int topCount, string sqlWhere, Dictionary<string, object> dbParams, string[] orderFields, bool isDesc, params string[] selectFields)
//        {
//            string sqlText;
//            GenerateTopCountSQLText(topCount, sqlWhere, dbParams, orderFields, isDesc, out sqlText, selectFields);
//            return GetDataReaderBySQL(sqlText, dbParams);
//        }

//        #endregion

//        #region 获得List的几个方法

//        /// <summary>
//        /// 将DataReader转换为List对象
//        /// </summary>
//        protected virtual List<TModel> GetListByDataReader(DbDataReader dbReader)
//        {
//            if (dbReader == null) return null;
//            List<TModel> list = new List<TModel>();
//            using (dbReader)
//            {
//                if (dbReader.HasRows)
//                {
//                    DataTable schemaTable = dbReader.GetSchemaTable();
//                    DataRow[] schemaRow;
//                    while (dbReader.Read())
//                    {
//                        TModel model = new TModel();
//                        Type type = model.GetType();
//                        System.Reflection.PropertyInfo[] pros = type.GetProperties();
//                        if (pros == null || pros.Length == 0) break;
//                        foreach (var item in pros)
//                        {
//                            if (!item.CanWrite) continue;
//                            string sName = item.Name;
//                            //判断实体中的属性是否存在该列名,不存在则跳出循环
//                            schemaRow = schemaTable.Select(string.Format("ColumnName='{0}'", sName));
//                            if (schemaRow.Length == 0) continue;
//                            if (dbReader[sName] != null && dbReader[sName].ToString().Trim() != string.Empty)
//                            {
//                                //如果DataReader没有将数据分类型存储,则使用以下方法转换
//                                object obj = Convert.ChangeType(dbReader[sName], item.PropertyType);
//                                //object obj = dbReader[sName];
//                                item.SetValue(model, obj, null);
//                            }
//                        }
//                        list.Add(model);
//                    }
//                }
//                else
//                {
//                    return null;
//                }
//            }
//            return list;
//        }

//        public virtual List<TModel> GetList(string sqlWhere, Dictionary<string, object> dbParams, string[] orderFields, bool isDesc, params string[] selectFields)
//        {
//            DbDataReader dbReader = GetDataReader(sqlWhere, dbParams, orderFields, isDesc, selectFields);
//            List<TModel> list = GetListByDataReader(dbReader);
//            return list;
//        }

//        public virtual List<TModel> GetListByPage(int onePageCount, int pageNo, bool isDesc, string[] orderField, out int pageCount, out int recordCount, string sqlWhere, Dictionary<string, object> dbParams, params string[] selectFields)
//        {
//            DbDataReader dbReader = GetDataReaderByPage(onePageCount, pageNo, isDesc, orderField, out pageCount, out recordCount, sqlWhere, dbParams, selectFields);
//            List<TModel> list = GetListByDataReader(dbReader);
//            return list;
//        }

//        public virtual List<TModel> GetListTopCount(int topCount, string sqlWhere, Dictionary<string, object> dbParams, string[] orderFields, bool isDesc, params string[] selectFields)
//        {
//            DbDataReader dbReader = GetDataReaderTopCount(topCount, sqlWhere, dbParams, orderFields, isDesc, selectFields);
//            List<TModel> list = GetListByDataReader(dbReader);
//            return list;
//        }

//        #endregion

//        #region 执行存储过程

//        public virtual int ExecProcedureGetNon(ProcedureObjBase procObj)
//        {
//            string procName = procObj.ToString();
//            Dictionary<string, object> procParam = procObj.GetProcParamObj();
//            DbParameter[] param = GetDbParam(procParam);
//            procObj.SetOutParam(ref param);
//            int r = DBHelper.ExecNonQuery(procName, CommandType.StoredProcedure, param);
//            procObj.SetOutParamValue(param);
//            return r;
//        }
//        public virtual DataTable ExecProcedureGetDataTable(ProcedureObjBase procObj)
//        {
//            string procName = procObj.ToString();
//            Dictionary<string, object> procParam = procObj.GetProcParamObj();
//            DbParameter[] param = GetDbParam(procParam);
//            procObj.SetOutParam(ref param);
//            DataTable r = DBHelper.GetDataTable(procName, CommandType.StoredProcedure, param);
//            procObj.SetOutParamValue(param);
//            return r;
//        }
//        public virtual object ExecProcedureGetObj(ProcedureObjBase procObj)
//        {
//            string procName = procObj.ToString();
//            Dictionary<string, object> procParam = procObj.GetProcParamObj();
//            DbParameter[] param = GetDbParam(procParam);
//            procObj.SetOutParam(ref param);
//            object r = DBHelper.GetScalar(procName, CommandType.StoredProcedure, param);
//            procObj.SetOutParamValue(param);
//            return r;
//        }

//        #endregion
//    }
//}
